home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * fliff.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
- *
- * Copyright (C) 1989,1990 by Michael Mauldin. Permission is granted
- * to use this file in whole or in part for any purpose, educational,
- * recreational or commercial, provided that this copyright notice
- * is retained unchanged. This software is available to all free of
- * charge by anonymous FTP and in the UUNET archives.
- *
- * fliff.c:
- *
- * CONTENTS
- * write_iff (image, stream)
- * read_iff (image, stream, mstr, mlen)
- *
- * EDITLOG
- * LastEditDate = Mon Jun 25 00:16:58 1990 - Michael Mauldin
- * LastFileName = /usr2/mlm/src/misc/fbm/fliff.c
- *
- * HISTORY
- * 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
- * Package for Release 1.0
- *
- * 06-Sep-89 Michael Mauldin (mlm) at Carnegie Mellon University
- * Beta release (version 0.96) mlm@cs.cmu.edu
- *
- * 04-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
- * Read and Write support for Amiga IFF (except HAM mode)
- *****************************************************************/
-
- # include <stdio.h>
- # include <math.h>
- # include <ctype.h>
- # include "fbm.h"
-
- #ifndef lint
- static char *fbmid =
- "$FBM fliff.c <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \
- code available free from MLM@CS.CMU.EDU and from UUNET archives$";
- #endif
-
- /****************************************************************
- * from iff.h
- ****************************************************************/
-
- # define BOOL int /* 1 bit value */
- # define SBYTE char /* 8 bits signend */
- # define UBYTE unsigned char /* 8 bits unsigned */
- # define WORD short /* 16 bits signed */
- # define UWORD unsigned short /* 16 bits unsigned */
- # define LONG long /* 32 bits signed */
- # define ID long
- # define MakeID(a,b,c,d) ( (LONG)(a)<<24L | (LONG)(b)<<16L | (c)<<8 | (d) )
- # define FORM MakeID('F','O','R','M')
- # define PROP MakeID('P','R','O','P')
- # define LIST MakeID('L','I','S','T')
- # define CAT MakeID('C','A','T',' ')
- # define FILLER MakeID(' ',' ',' ',' ')
- # define NULL_CHUNK 0L /* No current chunk.*/
- # define TRUE 1
- # define FALSE 0
-
-
- /* ---------- Chunk ----------------------------------------------------*/
-
- /* All chunks start with a type ID and a count of the data bytes that
- follow--the chunk's "logical size" or "data size". If that number is odd,
- a 0 pad byte is written, too. */
-
- typedef struct {
- ID ckID;
- LONG ckSize;
- } ChunkHeader;
-
- typedef struct {
- ID ckID;
- LONG ckSize;
- UBYTE ckData[ 1 /*REALLY: ckSize*/ ];
- } Chunk;
-
- /*----------------------------------------------------------------------*
- * ILBM.H Definitions for InterLeaved BitMap raster image. 1/23/86
- *
- * By Jerry Morrison and Steve Shaw, Electronic Arts.
- * This software is in the public domain.
- *
- * This version for the Commodore-Amiga computer.
- *----------------------------------------------------------------------*/
-
- # define ID_ILBM MakeID('I','L','B','M')
- # define ID_BMHD MakeID('B','M','H','D')
- # define ID_CMAP MakeID('C','M','A','P')
- # define ID_GRAB MakeID('G','R','A','B')
- # define ID_DEST MakeID('D','E','S','T')
- # define ID_SPRT MakeID('S','P','R','T')
- # define ID_CAMG MakeID('C','A','M','G')
- # define ID_BODY MakeID('B','O','D','Y')
-
- /* ---------- BitMapHeader ---------------------------------------------*/
-
- typedef UBYTE Masking; /* Choice of masking technique.*/
- # define mskNone 0
- # define mskHasMask 1
- # define mskHasTransparentColor 2
- # define mskLasso 3
-
- typedef UBYTE Compression; /* Choice of compression algorithm applied to
- * each row of the source and mask planes. "cmpByteRun1" is the byte run
- * encoding generated by Mac's PackBits. See Packer.h . */
- # define cmpNone 0
- # define cmpByteRun1 1
-
- /* Aspect ratios: The proper fraction xAspect/yAspect represents the pixel
- * aspect ratio pixel_width/pixel_height.
- *
- * For the 4 Amiga display modes:
- * 320 x 200: 10/11 (these pixels are taller than they are wide)
- * 320 x 400: 20/11
- * 640 x 200: 5/11
- * 640 x 400: 10/11 */
- # define x320x200Aspect 10
- # define y320x200Aspect 11
- # define x320x400Aspect 20
- # define y320x400Aspect 11
- # define x640x200Aspect 5
- # define y640x200Aspect 11
- # define x640x400Aspect 10
- # define y640x400Aspect 11
-
- /* A BitMapHeader is stored in a BMHD chunk. */
- typedef struct {
- UWORD w, h; /* raster width & height in pixels */
- WORD x, y; /* position for this image */
- UBYTE nPlanes; /* # source bitplanes */
- Masking masking; /* masking technique */
- Compression compression; /* compression algorithm */
- UBYTE pad1; /* UNUSED. For consistency, put 0 here.*/
- UWORD transparentColor; /* transparent "color number" */
- UBYTE xAspect, yAspect; /* aspect ratio, a rational number x/y */
- WORD pageWidth, pageHeight; /* source "page" size in pixels */
- } BitMapHeader;
-
- /* RowBytes computes the number of bytes in a row, from the width in pixels.*/
- # define RowBytes(w) (2 * (((w) + 15) / 16))
-
-
- /* ---------- ColorRegister --------------------------------------------*/
- /* A CMAP chunk is a packed array of ColorRegisters (3 bytes each). */
- typedef struct {
- UBYTE red, green, blue; /* MUST be UBYTEs so ">> 4" won't sign extend.*/
- } ColorRegister;
-
- /* Use this constant instead of sizeof(ColorRegister). */
- # define sizeofColorRegister 3
-
- typedef WORD Color4; /* Amiga RAM version of a color-register,
- * with 4 bits each RGB in low 12 bits.*/
-
- # define swapword(X) ((((X) & 0xff) << 8) | (((X) & 0xff00) >> 8))
- # define swaplong(X) (((unsigned) ((X) & 0xff000000) >> 24) | \
- ((unsigned) ((X) & 0x00ff0000) >> 8) | \
- ((unsigned) ((X) & 0x0000ff00) << 8) | \
- ((unsigned) ((X) & 0x000000ff) << 24))
-
- # define swapsize(X) ((machine_byte_order () == LITTLE) ? swaplong(X) : (X))
-
- /* Maximum number of bitplanes in RAM. Current Amiga max w/dual playfield. */
- # define MaxAmDepth 6
-
- /* Chunks must be padded to align to even boundaries */
- # define EVENALIGN(X) (((X) + 1) & ~1)
-
- /* ---------- Point2D --------------------------------------------------*/
- /* A Point2D is stored in a GRAB chunk. */
- typedef struct {
- WORD x, y; /* coordinates (pixels) */
- } Point2D;
-
- /* ---------- DestMerge ------------------------------------------------*/
- /* A DestMerge is stored in a DEST chunk. */
- typedef struct {
- UBYTE depth; /* # bitplanes in the original source */
- UBYTE pad1; /* UNUSED; for consistency store 0 here */
- UWORD planePick; /* how to scatter source bitplanes into destination */
- UWORD planeOnOff; /* default bitplane data for planePick */
- UWORD planeMask; /* selects which bitplanes to store into */
- } DestMerge;
-
- /* ---------- SpritePrecedence -----------------------------------------*/
- /* A SpritePrecedence is stored in a SPRT chunk. */
- typedef UWORD SpritePrecedence;
-
- /* ---------- Viewport Mode --------------------------------------------*/
- /* A Commodore Amiga ViewPort->Modes is stored in a CAMG chunk. */
- /* The chunk's content is declared as a LONG. */
-
- /* ---------- CRange ---------------------------------------------------*/
- /* A CRange is store in a CRNG chunk. */
- typedef struct {
- WORD pad1; /* reserved for future use; store 0 here */
- WORD rate; /* color cycling rate, 16384 = 60 steps/second */
- WORD active; /* nonzero means color cycling is turned on */
- UBYTE low, high; /* lower and upper color registers selected */
- } CRange;
-
- /*----------------------------------------------------------------------*
- * PACKER.H typedefs for Data-Compresser. 1/22/86
- *
- * This module implements the run compression algorithm "cmpByteRun1"; the
- * same encoding generated by Mac's PackBits.
- *
- * By Jerry Morrison and Steve Shaw, Electronic Arts.
- * This software is in the public domain.
- *
- * This version for the Commodore-Amiga computer.
- *----------------------------------------------------------------------*/
-
- /* This macro computes the worst case packed size of a "row" of bytes. */
- # define MaxPackedSize(rowSize) ( (rowSize) + ( ((rowSize)+127) >> 7 ) )
-
- /*----------------------------------------------------------------------*
- * unpacker.c Convert data from "cmpByteRun1" run compression. 11/15/85
- *
- * By Jerry Morrison and Steve Shaw, Electronic Arts.
- * This software is in the public domain.
- *
- * control bytes:
- * [0..127] : followed by n+1 bytes of data.
- * [-1..-127] : followed by byte to be repeated (-n)+1 times.
- * -128 : NOOP.
- *
- * This version for the Commodore-Amiga computer.
- *----------------------------------------------------------------------*/
-
- /*----------- UnPackRow ------------------------------------------------*/
-
- # define UGetByte() (*source++)
- # define UPutByte(c) (*dest++ = (c))
-
- /* Given POINTERS to POINTER variables, unpacks one row, updating the source
- * and destination pointers until it produces dstBytes bytes. */
- static UnPackRow(pSource, pDest, srcBytes0, dstBytes0)
- char **pSource, **pDest; int srcBytes0, dstBytes0; {
- register char *source = *pSource;
- register char *dest = *pDest;
- register int n;
- register char c;
- register int srcBytes = srcBytes0, dstBytes = dstBytes0;
- BOOL error = TRUE; /* assume error until we make it through the loop */
-
-
- # ifdef DEBUG
- fprintf (stderr, "Unpack called, src %d, dst %d\n",
- srcBytes0, dstBytes0);
- # endif
-
- while( dstBytes > 0 ) {
- if ( (srcBytes -= 1) < 0 ) goto ErrorExit;
- n = UGetByte() & 0x0ff;
-
- if (n < 128) {
- # ifdef DEBUG
- fprintf (stderr, "Got %02x, copying %d bytes...\n", n, n+1);
- # endif
-
- n += 1;
-
- if ( (srcBytes -= n) < 0 ) goto ErrorExit;
- if ( (dstBytes -= n) < 0 ) goto ErrorExit;
- do { UPutByte(UGetByte()); } while (--n > 0);
- }
-
- else if (n != 128) {
- # ifdef DEBUG
- fprintf (stderr, "Got %02x, repeating byte %d times...\n",
- n, 257-n);
- # endif
-
- n = 257 - n;
-
- if ( (srcBytes -= 1) < 0 ) goto ErrorExit;
- if ( (dstBytes -= n) < 0 ) goto ErrorExit;
- c = UGetByte();
- do { UPutByte(c); } while (--n > 0);
- }
- }
- error = FALSE; /* success! */
-
- ErrorExit:
- *pSource = source; *pDest = dest;
-
- if (error)
- { fprintf (stderr, "error in unpack, src %d, dst %d\n",
- srcBytes, dstBytes);
- }
-
- return(error);
- }
-
- /****************************************************************
- * read_iff: Read an Amiga format IFF Interleaved Bitmap
- ****************************************************************/
-
- read_iff (image, rfile, mstr, mlen)
- FBM *image;
- FILE *rfile;
- char *mstr;
- int mlen;
- { char magic[8];
- long formsize, buflen;
- Chunk *form;
- int result;
-
- /* First word is magic number */
- magic[0] = NEXTMCH(rfile,mstr,mlen) & 0xff;
- magic[1] = NEXTMCH(rfile,mstr,mlen) & 0xff;
- magic[2] = NEXTMCH(rfile,mstr,mlen) & 0xff;
- magic[3] = NEXTMCH(rfile,mstr,mlen) & 0xff;
- magic[4] = '\0';
-
- /* If magic number is not FORM, lose */
- if (strcmp (magic, "FORM") != 0)
- { if (strncmp (magic, "FOR", 3) == 0 ||
- strncmp (magic, "LIS", 3) == 0 ||
- strncmp (magic, "CAT", 3) == 0)
- { fprintf (stderr, "Sorry, I only handle FORM type IFF files\n");
- return (0);
- }
-
- fprintf (stderr,
- "read_iff: error, file not a FORM type IFF file, magic '%s'\n",
- magic);
- return (0);
- }
-
- /* Second longword is length of data chunk */
- formsize = get_long (rfile, BIG);
-
- form = (Chunk *) malloc (formsize + 8);
- form->ckID = FORM;
- form->ckSize = formsize;
-
- /* Now read the rest of the chunk */
- if ((buflen = fread (form->ckData, 1, formsize, stdin)) < formsize)
- { if (buflen < 0)
- { perror ("stdin"); }
- else
- { fprintf (stderr, "error: premature EOF in FORM after %d of %d bytes\n",
- buflen, formsize);
- }
-
- exit (1);
- }
-
- /* Recursively parse the FORM */
- result = parse_form (image, form);
-
- /* Now we've read the image (or not) */
- free (form);
-
- return (result);
- }
-
- /****************************************************************
- * parse_form: Parse an IFF form chunk
- *
- * FORM ::= "FORM" #{ FormType (LocalChunk | FORM | LIST | CAT)* }
- * FormType ::= ID
- * LocalChunk ::= Property | Chunk
- ****************************************************************/
-
- parse_form (image, chunk)
- FBM *image;
- Chunk *chunk;
- { register UBYTE *data, *tail;
- register int clrlen, colors;
- register BitMapHeader *bmh;
- register int i, bits;
- long formtype;
- int found_bmhd=0, found_cmap=0, found_body=0;
- Chunk *part;
-
- data = chunk->ckData;
- tail = data + chunk->ckSize;
-
- formtype = MakeID(data[0], data[1], data[2], data[3]);
- data += 4;
-
- if (formtype != ID_ILBM)
- { fprintf (stderr, "this FORM doesn't start with ILBM, but %4.4s, sorry.\n",
- &formtype);
- return (0);
- }
-
- while (data < tail)
- { part = (Chunk *) data;
- part->ckID = swapsize (part->ckID);
- part->ckSize = swapsize (part->ckSize);
- data += ( EVENALIGN (part->ckSize) + 8 );
-
- # ifdef DEBUG
- fprintf (stderr, "Found %c%c%c%c, size %ld\n",
- (part->ckID & 0xff000000) >> 24,
- (part->ckID & 0x00ff0000) >> 16,
- (part->ckID & 0x0000ff00) >> 8,
- (part->ckID & 0x000000ff),
- part->ckSize);
- # endif
-
- if (part->ckID == ID_BMHD)
- { found_bmhd++;
- bmh = (BitMapHeader *) part->ckData;
-
- /* IFF uses BIG byte order, swap if necessary */
- if (machine_byte_order () == LITTLE)
- { bmh->w = swapword (bmh->w);
- bmh->h = swapword (bmh->h);
- bmh->x = swapword (bmh->x);
- bmh->y = swapword (bmh->y);
- bmh->transparentColor = swapword (bmh->transparentColor);
- bmh->pageWidth = swapword (bmh->pageWidth);
- bmh->pageHeight = swapword (bmh->pageHeight);
- }
-
- image->hdr.rows = bmh->h;
- image->hdr.cols = bmh->w;
- image->hdr.planes = 1;
- image->hdr.bits = bmh->nPlanes;
- image->hdr.physbits = 8;
- image->hdr.rowlen = 2 * ((image->hdr.cols + 1) / 2);
- image->hdr.plnlen = image->hdr.rowlen * image->hdr.rows;
- image->hdr.clrlen = 0;
- image->hdr.aspect = (double) bmh->yAspect / bmh->xAspect;
- image->hdr.title[0] = '\0';
- image->hdr.credits[0] = '\0';
- }
- else if (part->ckID == ID_CMAP)
- { image->hdr.clrlen = part->ckSize;
-
- alloc_fbm (image);
-
- clrlen = image->hdr.clrlen;
- colors = clrlen / 3;
-
- for (i=0; i<image->hdr.clrlen; i++)
- { image->cm[(colors * (i%3)) + i/3] = part->ckData[i]; }
-
- /* Compute number of bits in colormap */
- for (i=colors, bits=1; i > 2; i /= 2, bits++) ;
-
- if (bits < image->hdr.bits) image->hdr.bits = bits;
-
- found_cmap++;
- }
- else if (part->ckID == ID_BODY)
- { if (!found_bmhd)
- { fprintf (stderr, "Error, BODY found with no BMHD header\n");
- return (0);
- }
-
- if (found_cmap == 0)
- { alloc_fbm (image); }
-
- found_body++;
-
- /* Decode body */
- fprintf (stderr, "Reading IFF [%dx%dx%d], %d physbits, %1.3lf aspect",
- image->hdr.cols, image->hdr.rows,
- image->hdr.bits, image->hdr.physbits,
- image->hdr.aspect);
- if (image->hdr.planes > 1)
- { fprintf (stderr, ", %d planes", image->hdr.planes); }
- if (image->hdr.clrlen > 1)
- { fprintf (stderr, ", %d colors", image->hdr.clrlen / 3); }
- if (bmh->compression)
- { fprintf (stderr, ", compressed"); }
- if (bmh->masking == mskHasMask)
- { fprintf (stderr, ", with mask"); }
- fprintf (stderr, "\n");
-
- # ifdef DEBUG
- fprintf (stderr,
- "masking %d, compression %d, transparent %d, page [%dx%d]\n",
- bmh->masking, bmh->compression, bmh->transparentColor,
- bmh->pageWidth, bmh->pageHeight);
-
- for (i=0; i<colors; i++)
- { fprintf (stderr, " color %3d: <%3d, %3d, %3d>\n", i,
- image->cm[i], image->cm[i+colors], image->cm[i+colors*2]);
- }
- # endif
-
- return (read_iff_body (image, bmh, part));
- }
- }
-
- return (0);
- }
-
- /****************************************************************
- * read_iff_body: Read the bits in the ILBM body into the FBM image
- ****************************************************************/
-
- read_iff_body (image, bmh, body)
- FBM *image;
- BitMapHeader *bmh;
- Chunk *body;
- { register int r, c, k, pmask, byte, bit;
- unsigned char *row, *bp, *buf, *obm, *tail;
- int bytlen = image->hdr.cols / 8;
- int planes = bmh->nPlanes + ((bmh->masking == mskHasMask) ? 1 : 0);
-
- buf = (unsigned char *) malloc (bytlen);
-
- bp = body->ckData;
- tail = bp + body->ckSize;
-
- # ifdef DEBUG
- fprintf (stderr, "Body length %d, planes %d: ", tail-bp, planes);
- for (c=0; c<20; c++) fprintf (stderr, "%02x", bp[c]);
- fprintf (stderr, "\n");
- # endif
-
- /* Each iteration reads one scan line */
- for (r=0; r<image->hdr.rows; r++)
- {
- if (bp > tail)
- { fprintf (stderr, "Ran out of data in body after %d of %d rows\n",
- r, image->hdr.rows);
- return (0);
- }
-
- obm = &(image->bm[r * image->hdr.rowlen]);
-
- /* Clear the output row of pixels */
- for (c=0; c<image->hdr.cols; c++)
- { obm[c] = 0; }
-
- /* Each loop reads one plane of this scan line */
- for (k=0; k<planes; k++)
- {
- /* First get pointer to data packed 8 bits per byte */
- if (bmh->compression == 0)
- { row = bp; bp += RowBytes (bmh->w); }
- else
- { row = buf;
- if (UnPackRow ((char **)&bp, (char **)&row, (int)(tail-bp),
- RowBytes (bmh->w)) != 0)
- { fprintf (stderr,
- "%s, row %d of %d, plane %d of %d, bytes per row %d\n",
- "Error in UnPackRow",
- r, image->hdr.rows, k, planes, RowBytes (bmh->w));
- return (0);
- }
- row = buf;
- }
-
- /* Ignore extra planes (including the mask if any) */
- if (k >= image->hdr.bits)
- continue;
-
- /* Now OR in these bits into the output pixels */
- pmask = 1 << k;
-
- for (c=0; c<image->hdr.cols; c++)
- { byte = c >> 3;
- bit = 7 - (c & 7);
- bit = row[byte] & (1 << bit);
-
- obm[c] |= bit ? pmask : 0;
- }
- }
- }
-
- if (tail-bp > 1)
- { fprintf (stderr, "Warning, %d bytes of data unread\n", tail - bp); }
-
- return (1);
- }
-
- /****************************************************************
- * write_iff: Write AMIGA IFF format ILBM file
- *
- * Writes FORM type ILBM
- * BMHD
- * CMAP (optional)
- * BODY (uncompressed)
- *
- ****************************************************************/
-
- write_iff (image, wfile)
- FBM *image;
- FILE *wfile;
- { BitMapHeader bmhd;
- unsigned char *cmap, *body;
- int bodylen, cmaplen, bmhdlen, formlen, ilbmbits;
-
- if (image->hdr.planes > 1)
- { fprintf (stderr, "Error, write_iff cannot handle multi-plane images\n");
- return (0);
- }
-
- /* Determine number of bits in output */
- if (image->hdr.clrlen == 0)
- { ilbmbits = image->hdr.bits; }
- else
- { int colors = image->hdr.clrlen/3;
- for (ilbmbits=1; colors > 2; ilbmbits++, colors >>= 1) ;
- }
-
- fprintf (stderr, "Writing \"%s\" [%dx%d] as a %d bit IFF ILBM file\n",
- image->hdr.title[0] ? image->hdr.title : "",
- image->hdr.cols, image->hdr.rows, ilbmbits);
-
- if (ilbmbits > 5)
- { fprintf (stderr, "%s\n%s\n%s\n",
- "Warning: most IFF ILBM displays cannot handle more than",
- " 32 colors. You should probably run the image though",
- " 'gray2clr -u | fbquant -c32' first.");
- }
-
- /* Build BMHD, CMAP, and body chunks */
- bmhdlen = build_bmhd (image, &bmhd, ilbmbits) ;
- cmaplen = build_cmap (image, &cmap, ilbmbits);
- bodylen = build_body (image, &body, ilbmbits);
-
- /* Length of FORM is length of subparts plus 8 for header + 4 for type */
- formlen = bmhdlen + cmaplen + bodylen + 12;
-
- /*--------Write out FORM chunk header--------*/
- fprintf (wfile, "FORM");
- put_long (formlen-8, wfile, BIG);
- fprintf (wfile, "ILBM");
-
- /*----Write out BMHD chunk----*/
- fprintf (wfile, "BMHD");
- put_long (bmhdlen-8, wfile, BIG);
- fwrite (&bmhd, bmhdlen-8, 1, wfile);
-
- /* No need to pad BMHD chunk, it must be even */
-
- /*----Write out CMAP chunk----*/
- if (cmaplen > 0)
- { fprintf (wfile, "CMAP");
- put_long (cmaplen-8, wfile, BIG);
- fwrite (cmap, cmaplen-8, 1, wfile);
-
- /* Pad CMAP chunk if necessary */
- if (cmaplen & 1) fputc (0, wfile);
- }
-
- /*----Write out BODY chunk----*/
- fprintf (wfile, "BODY");
- put_long (bodylen-8, wfile, BIG);
- fwrite (body, bodylen-8, 1, wfile);
-
- /* Pad BODY chunk if necessary */
- if (bodylen & 1) fputc (0, wfile);
-
- /*--------Free memory and return--------*/
- if (cmap) free (cmap);
- if (body) free (body);
-
- return (1);
- }
-
- /****************************************************************
- * build_bmhd: Build a BitMapHeader, and byte swap it if necessary
- ****************************************************************/
-
- build_bmhd (image, bmh, bits)
- FBM *image;
- BitMapHeader *bmh;
- int bits;
- {
- bmh->w = image->hdr.cols;
- bmh->h = image->hdr.rows;
- bmh->x = 0;
- bmh->y = 0;
- bmh->nPlanes = bits;
- bmh->masking = 0;
- bmh->compression = 0;
- bmh->pad1 = 0;
- bmh->transparentColor = 0;
- bmh->xAspect = 100;
- bmh->yAspect = (image->hdr.aspect * 100.0) + 0.5;
- bmh->pageWidth = bmh->w;
- bmh->pageHeight = bmh->h;
-
- /* IFF uses BIG byte order, swap if necessary */
- if (machine_byte_order () == LITTLE)
- { bmh->w = swapword (bmh->w);
- bmh->h = swapword (bmh->h);
- bmh->x = swapword (bmh->x);
- bmh->y = swapword (bmh->y);
- bmh->transparentColor = swapword (bmh->transparentColor);
- bmh->pageWidth = swapword (bmh->pageWidth);
- bmh->pageHeight = swapword (bmh->pageHeight);
- }
-
- return (sizeof (*bmh) + 8);
- }
-
- /****************************************************************
- * build_cmap: Convert an FBM format colormap to IFF format
- ****************************************************************/
-
- build_cmap (image, cmap, bits)
- FBM *image;
- unsigned char **cmap;
- int bits;
- { register int len, i;
- register unsigned char *r, *g, *b, *c;
- int colors;
-
- colors = image->hdr.clrlen / 3;
-
- r = image->cm;
- g = r + colors;
- b = g + colors;
-
- len = 3*colors;
- *cmap = (unsigned char *) malloc (len);
-
- /* Now convert from three vectors to a vector of triples */
- for (i=0, c= *cmap; i<colors; i++)
- { *c++ = *r++;
- *c++ = *g++;
- *c++ = *b++;
- }
-
- /* Return length of chunk, just length of map plus 8 bytes chunk header */
- return (len + 8);
- }
-
- /****************************************************************
- * build_body: Interleave the bits for the byte plane
- ****************************************************************/
-
- build_body (image, body, bits)
- register FBM *image;
- unsigned char **body;
- int bits;
- { int bpr, size;
- register unsigned char *obm, *bmp;
- register int r, c, k, mask, byte, bit;
-
- bpr = RowBytes (image->hdr.cols);
-
- size = bpr * image->hdr.rows * bits;
-
- *body = (unsigned char *) malloc (size);
-
- obm = *body;
-
- for (r=0; r < image->hdr.rows; r++)
- { for (k=0; k<bits; k++)
- { mask = 1 << k;
- bmp = &(image->bm[r * image->hdr.rowlen]);
-
- # ifdef DEBUG
- if (r==23)
- { fprintf (stderr, "Row %d, plane %d, bytes: ", r, k);
- for (c=0; c<32; c++) fprintf (stderr, "%02x", bmp[c]);
- fprintf (stderr, "\n");
- }
- # endif
-
- for (c=0, byte=0; c<image->hdr.cols; c++)
- { bit = (*bmp++ & mask) ? 1 : 0;
-
-
- # ifdef DEBUG
- if (r == 23 && c < 32)
- { fprintf (stderr, "%d", bit); }
- # endif
-
- byte = (byte << 1) | bit;
- if ((c&7) == 7)
- { *obm++ = byte;
-
- # ifdef DEBUG
- if (r == 23 && c <32) fprintf (stderr, " %d ", byte);
- # endif
-
- byte=0;
- }
- }
-
- # ifdef DEBUG
- if (r == 23) fprintf (stderr, "\n");
- # endif
-
- if ((c & 7) != 0)
- { while ((c&7) != 0)
- { c++; byte <<= 1; }
- *obm++ = byte;
- }
- }
- }
-
- return (size + 8);
-
- }
-